
#include "VisualObservationDialog.h"

#include "MessageDialog.h"
#include <QtGui>
#include <QtNetwork>


/**
 * Tworzy okno formularza dodawania obserwacji wizualnej.
 *
 * @param mgr obiekt zarządzający połączeniem internetowym
 * @param parent obiekt rodzica
 */
VisualObservationDialog::VisualObservationDialog(QNetworkAccessManager* mgr,
        QWidget *parent): QDialog(parent)
{
	ui.setupUi(this);

	// autouzupełnianie nazwy gwiazdy
	QStringList starNames = Dogz::StarManager::getNames();
    if (!starNames.isEmpty())
    {
        QCompleter* completer = new QCompleter(starNames, this);
        completer->setCaseSensitivity(Qt::CaseInsensitive);
        ui.editStarName->setCompleter(completer);
    }
    // walidacja pól
    ui.editJd->setValidator(new QDoubleValidator(this));
    ui.editMagnitude->setValidator(new QDoubleValidator(this));
    // dopasowujemy szerokość
    ui.gbxAavsoInformation->setMinimumSize(ui.gbxBaseInformation->sizeHint());
    ui.gbxAavsoInformation->setMaximumSize(ui.gbxBaseInformation->sizeHint());
    // wstępnie ukrywamy formularz dla AAVSO
    layout()->setSizeConstraint(QLayout::SetFixedSize);
    ui.gbxAavsoInformation->hide();

    // własne zarządzanie gwiazdami, żeby nie wywoływać slotów okna głównego
    starManager = new Dogz::StarManager(this);
    starManager->setNetworkManager(mgr);
    connect(starManager, SIGNAL(starFound(Dogz::Star)),
            this, SLOT(showStarInfo(Dogz::Star)));

    // aktualizacja stanu przycisku "Dodaj"
    connect(ui.editJd, SIGNAL(textChanged(QString)), this, SLOT(updateUi()));
    connect(ui.editMagnitude, SIGNAL(textChanged(QString)), this, SLOT(updateUi()));
    updateUi();
}

/**
 * Wyświetla pomocnicze informacje o gwieździe wpisanej w polu edycyjnym.
 *
 * @param star obiekt gwiazdy
 */
void VisualObservationDialog::showStarInfo(Dogz::Star star)
{
    if (star.isValid())
    {
        QString info = tr("<b>%1</b><br>"
                "<br>Typ: %2"
                "<br>Max: %3 mag."
                "<br>Min: %4 mag.").
                arg(star.getName()).arg(star.getType()).
                arg(star.getMaxMagnitude()).arg(star.getMinMagnitude());
        ui.lblStarInfo->setText(info);
    }
    else
    {
        ui.lblInfo->setText(tr("Gwiazda nieznana w GCVS."));
    }
}

/**
 * Po kliknięciu przycisku ustawia bieżącą datę w polu edycyjnym.
 */
void VisualObservationDialog::on_btnDateTimeNow_clicked()
{
    ui.editDateTime->setDateTime(QDateTime::currentDateTime());
}

/**
 * Przy zmianie daty automatycznie aktualizuje JD w polu poniżej.
 *
 * @param date nowa data
 */
void VisualObservationDialog::on_editDateTime_dateTimeChanged(
        const QDateTime& date)
{
    ui.editJd->setText(JdTools::dateToJd(date, JdTools::AsString));
}

/**
 * Dodaje nową obserwację do bazy danych.
 */
void VisualObservationDialog::on_btnAddObservation_clicked()
{
    // weryfikacja błędów formularza
    if (hasValidObservation())
    {
        // tworzenie obiektu obserwacji na podstawie pól formularza
        Dogz::VisualObservation obs;
        obs.setStarName(ui.editStarName->text());
        obs.setJd(ui.editJd->text().toDouble());
        obs.setMagnitude(ui.editMagnitude->text().toFloat());
        obs.setFainterThan(ui.cbxFainterThan->isChecked());
        obs.setCompStarName(ui.editCompStarName->text());
        obs.setChartDate(ui.editChartDate->text());
        obs.setCommentCodes(ui.editCommentCodes->text());
        obs.setNotes(ui.editNotes->toPlainText());

        // właściwy zapis do bazy
        try
        {
            Dogz::ObservationManager::addObservation(obs);
            ui.lblInfo->setText(tr("Dodano: %1").arg(obs.toString()));
        }
        catch (Dogz::DbException& e)
        {
            MessageDialog::exception(e);
        }
    }
}

/**
 * Weryfikuje poprawność wprowadzonej obserwacji.
 *
 * @return true, jeśli formularz w okienku zawiera poprawne dane
 */
bool VisualObservationDialog::hasValidObservation()
{
    // data z przyszłości (z małym marginesem)
    if (ui.editJd->text().toDouble() > (JdTools::currentJd() + 0.01))
    {
        if (QMessageBox::No == QMessageBox::question(this, tr("DOGZ"),
                tr("JD: %1 wygląda na pochodzące z przyszłości (%2)\n"
                "Czy na pewno chcesz dodać tę obserwację?").
                    arg(ui.editJd->text()).
                    arg(JdTools::jdToDate(ui.editJd->text()).toString()),
                QMessageBox::Yes | QMessageBox::No))
        {
            return false;
        }
    }

    // data bez początkowego 24
    if (!ui.editJd->text().startsWith("24"))
    {
        if (QMessageBox::Yes == QMessageBox::question(this, tr("DOGZ"),
                tr("Podane JD (%1) nie zaczyna się od 24\n"
                "Dodać 24 na poczatku?").
                    arg(ui.editJd->text()),
                QMessageBox::Yes | QMessageBox::No))
        {
            ui.editJd->setText("24" + ui.editJd->text());
        }
    }

    return true;
}

/**
 * Szuka gwiazdy w bazie danych. Jeśli to się nie uda, pyta GCVS.
 */
void VisualObservationDialog::on_editStarName_editingFinished()
{
    QString starName = Dogz::Star::normalizeStarName(ui.editStarName->text());

    // działamy tylko wtedy, gdy nazwa gwiazdy się faktycznie zmieniła
    if (starName != previousStarName)
    {
        ui.editStarName->setText(starName);
        if (!starName.isEmpty())
            starManager->findStarByName(starName);

        previousStarName = starName;
    }

    updateUi();
}

/**
 * Wywoływane w momencie zmiany wartości kontrolek.
 *
 * Włącza/wyłącza przycisk "Dodaj obserwacje".
 */
void VisualObservationDialog::updateUi()
{
    bool enabled = false;

    if (!ui.editStarName->text().isEmpty() &&
            ui.editJd->hasAcceptableInput() &&
            ui.editMagnitude->hasAcceptableInput())
    {
        enabled = true;
    }

    ui.btnAddObservation->setEnabled(enabled);
}
